package com.pai4j.message.core.provider;

import com.pai4j.message.model.ResourceInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;

import jakarta.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 资源提供者抽象基类
 * 实现通用的缓存和批处理逻辑
 *
 * @author PAI4J Team
 * @date 2025-11-01
 */
@Slf4j
public abstract class AbstractResourceProvider implements ResourceProvider {

    @Autowired(required = false)
    private CacheManager cacheManager;

    /**
     * 缓存名称
     */
    private static final String CACHE_NAME = "resource-info";

    /**
     * 自动注册
     */
    @PostConstruct
    public void autoRegister() {
        ResourceRegistry.register(this);
        log.info("ResourceProvider自动注册: type={}, class={}", 
                getResourceType(), this.getClass().getSimpleName());
    }

    @Override
    public ResourceInfo getResourceInfo(String resourceId) {
        if (resourceId == null || resourceId.trim().isEmpty()) {
            return null;
        }

        // 尝试从缓存获取
        ResourceInfo cached = getFromCache(resourceId);
        if (cached != null) {
            log.debug("从缓存获取资源信息: type={}, id={}", getResourceType(), resourceId);
            return cached;
        }

        // 从数据源获取
        try {
            ResourceInfo info = doGetResourceInfo(resourceId);
            
            // 写入缓存
            if (info != null) {
                putToCache(resourceId, info);
            }
            
            return info;
            
        } catch (Exception e) {
            log.error("获取资源信息失败: type={}, id={}, error={}", 
                    getResourceType(), resourceId, e.getMessage(), e);
            return null;
        }
    }

    @Override
    public String getResourceOwner(String resourceId) {
        ResourceInfo info = getResourceInfo(resourceId);
        return info != null ? info.getOwnerId() : null;
    }

    @Override
    public Map<String, ResourceInfo> batchGetResourceInfo(List<String> resourceIds) {
        Map<String, ResourceInfo> result = new HashMap<>();
        
        if (resourceIds == null || resourceIds.isEmpty()) {
            return result;
        }

        // 尝试批量获取
        try {
            Map<String, ResourceInfo> batchResult = doBatchGetResourceInfo(resourceIds);
            if (batchResult != null && !batchResult.isEmpty()) {
                // 批量写入缓存
                for (Map.Entry<String, ResourceInfo> entry : batchResult.entrySet()) {
                    putToCache(entry.getKey(), entry.getValue());
                }
                return batchResult;
            }
        } catch (Exception e) {
            log.warn("批量获取资源信息失败，降级为逐个获取: error={}", e.getMessage());
        }

        // 降级：逐个获取
        for (String resourceId : resourceIds) {
            ResourceInfo info = getResourceInfo(resourceId);
            if (info != null) {
                result.put(resourceId, info);
            }
        }

        return result;
    }

    /**
     * 从数据源获取资源信息（子类实现）
     */
    protected abstract ResourceInfo doGetResourceInfo(String resourceId);

    /**
     * 批量获取资源信息（子类可选实现）
     */
    protected Map<String, ResourceInfo> doBatchGetResourceInfo(List<String> resourceIds) {
        // 默认实现：逐个获取
        Map<String, ResourceInfo> result = new HashMap<>();
        for (String resourceId : resourceIds) {
            ResourceInfo info = doGetResourceInfo(resourceId);
            if (info != null) {
                result.put(resourceId, info);
            }
        }
        return result;
    }

    /**
     * 从缓存获取
     */
    private ResourceInfo getFromCache(String resourceId) {
        if (cacheManager == null) {
            return null;
        }

        try {
            Cache cache = cacheManager.getCache(CACHE_NAME);
            if (cache != null) {
                String cacheKey = getCacheKey(resourceId);
                Cache.ValueWrapper wrapper = cache.get(cacheKey);
                if (wrapper != null) {
                    return (ResourceInfo) wrapper.get();
                }
            }
        } catch (Exception e) {
            log.warn("从缓存获取资源信息失败: {}", e.getMessage());
        }

        return null;
    }

    /**
     * 写入缓存
     */
    private void putToCache(String resourceId, ResourceInfo info) {
        if (cacheManager == null || info == null) {
            return;
        }

        try {
            Cache cache = cacheManager.getCache(CACHE_NAME);
            if (cache != null) {
                String cacheKey = getCacheKey(resourceId);
                cache.put(cacheKey, info);
            }
        } catch (Exception e) {
            log.warn("写入缓存失败: {}", e.getMessage());
        }
    }

    /**
     * 生成缓存Key
     */
    private String getCacheKey(String resourceId) {
        return String.format("%s:%s", getResourceType(), resourceId);
    }

    /**
     * 清除缓存
     */
    protected void evictCache(String resourceId) {
        if (cacheManager == null) {
            return;
        }

        try {
            Cache cache = cacheManager.getCache(CACHE_NAME);
            if (cache != null) {
                String cacheKey = getCacheKey(resourceId);
                cache.evict(cacheKey);
                log.debug("清除资源缓存: key={}", cacheKey);
            }
        } catch (Exception e) {
            log.warn("清除缓存失败: {}", e.getMessage());
        }
    }
}

